#pragma once

#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <vector>


/*========================================<工具函数>========================================*/
struct FileHeader
{
    char filename[128]; // 文件名
    long long filesize;   // 文件大小

    FileHeader()
    {
        memset(filename, 0, sizeof(filename));
        filesize = 0;
    }

    void setFilename(const std::string& name)
    {
        strncpy(filename, name.c_str(), sizeof(filename) - 1);
        filename[sizeof(filename) - 1] = '\0'; // 确保null终止
    }

    std::string getFilename() const
    {
        return std::string(filename);
    }
};


/*========================================<网络地址类>========================================*/

class InetAddress
{
public:
    struct sockaddr_in addr;
    socklen_t addr_len;
    InetAddress();
    InetAddress(const char* ip, uint16_t port);
    ~InetAddress();
};

/*========================================<socket套接字类>========================================*/

class Socket
{
private:
    int fd;
public:
    Socket();
    Socket(int fd);
    ~Socket();

    int getFd()const;
    void setFd(int fd);

    void setnonblocking();

    void bind(InetAddress* ServerInetAddr);
    void listen(int backLog);
    int accept(InetAddress* clientInetAddr);

    ssize_t sendAll(const void* buf, size_t len); // 确保发送所有数据
    ssize_t recvAll(void* buf, size_t len); // 确保接收所有数据

    ssize_t recv(void* buf, size_t len);//非阻塞形式，为了传输文件
};

/*========================================<epoll边缘触发类，IO多路复用>========================================*/

#define MAX_EVENTS 1024

class EpollET
{
private:
    int epfd;
public:
    struct epoll_event* events;
public:
    EpollET();
    ~EpollET();

    int getEpfd()const;

    int add_fd(int fd, uint32_t op);
    std::vector<epoll_event> poll(int timeout = -1);
};